My PALette Remembered!
The Perpetual Newbie - Log Entry #10.0
by Gary Mugford - mugford@aztec-net.com
New computers are great! Usually they mean more of everything, speed, memory, storage space … trouble! That’s trouble as in re-installing pains. Some people get around re-installing by using DiskImage or some such utility to replicate the OLD system. Seems counter-productive to me. And besides, I clean out my computer, new or not, each Spring and Fall. So, I have fallen into the habit of needing a listing of what is active in my Delphi and what’s to be discarded.
Unfortunately, there’s no handy VCL lister that I can find within Delphi itself. I’d love one that listed each component and where it was installed from. Haven’t got the answer to the full question, but I DID produce a program that will give me a listing I can do something with.
What follows is the basic code I used to produce the program. There are some interesting techniques for Newbies (such as buying the Registry handling tool from TurboPower [G]). But note the use of the routine to create a temporary data table (not so temp actually) and the CommaTextToStrings function that is very largely overlooked. This program DOES presume BDE, but building your own with whatever engine should be simple.
The program works for me. I haven’t tried it with Delphi 6.0 for the obvious reason of not having it yet. And I SHOULD error-proof the section for reading the Registry so that it doesn’t choke if you don’t have the key in question. But it works fine for me with just that little care to only load registry settings for the versions I actually have [G].
I include my version with this article (click here). Using BDE, it’s a tad large, even zipped up. If any of you want to carry the ball with more portable temporary data storage and release it here to the other readers of UNDU, please feel free to do so. We’re all here to help each other out.
Here's the project stuff:
{---------------------------------------------------
Design a form with a dataset called TblPalette and
SourcePalette. Add a grid and a navigator for the
dataset. Add four buttons, labelled LOAD, FILL, PRINT
and EXIT. Put a memo (not a DBmemo) on the form. Create
a couple of check boxes labelled FILTER OUT HIDDEN? and
CAPITALIZE NAMES. Make both checked. Set up a radio group
with three choices, 4,5,6 defaulting to 5. I recommend
names in the text below. But you get are obviously allowed
to differ. Initially, set the table and the FILL and
PRINT buttons to inactive. GM
---------------------------------------------------------}var
FrmMain: TFrmMain;
const
ChopAt = 1;Procedure TFrmMain.FormCreate(Sender: TObject);
begin
memoRegistryExtract.clear; // empty the holding memo
CreateDPaletteTable; // create the data table if necessary
tblPalette.active := true; // activate the table
end;Procedure TFrmMain.CreateDPaletteTable;
begin
if not fileExists('DPalette.DB') // check to see if it exists in app dir
then with TTable.Create(Application) do
begin
Active := False;
DatabaseName := ExtractFilePath(application.ExeName);
TableName := 'DPalette';
TableType := ttDefault;
With FieldDefs do begin
Add('Seq', ftInteger, 0, False); // tab sequence number
Add('Pg', ftString, 30, False); // tab page name
Add('Vcl', ftString, 45, False); // component name
// Following are check boxes for install style, After the fact edit
Add('Dcu', ftBoolean, 0, False);
Add('Pas', ftBoolean, 0, False);
Add('Dpk', ftBoolean, 0, False);
Add('BPL', ftBoolean, 0, False);
// field for whatever you want to add after the fact
Add('Comment', ftString, 30, False);
end;
// Set up a primary index and on on the component name
with IndexDefs do begin
Add('', 'Seq;Pg;Vcl', [ixPrimary, ixUnique]);
Add('onVCL', 'Vcl;Pg', [ixUnique]);
end;
try CreateTable;
finally Free;
end;
end;
end;{----------------------------------------------------------------------------
The Registry loading section uses TurboPower's SysTools routines to load the
whole key into the memo field. The component is STRegIni. I think SysTools is
an indispensible tool for any programmer, and frankly can't live without it.
However, if you want some alternatives, a search of www.tamarack.com or of
Torry's Delphi site will surely provide you with some freeware registry
handling tools. But check out SysTools at www.turbopower.com
-----------------------------------------------------------------------------}procedure TFrmMain.BtnLoadRegClick(Sender: TObject);
var
k : integer; // lines index zero based
KL : TStringList; // store a list of values in the subkey
KReg : TSTRegIni; // Access variable for the registry
vNum : string[1]; // Holds the version number as a string
begin
memoRegistryExtract.clear; // clear memo each time button pushed
case radiogoupVersion.itemIndex of // get the version from the radio group
0 : vNum := '4';
1 : vNum := '5';
else vNum := '6';
end;
try kL := TStringList.create;
try KReg := TSTRegIni.create(RICuser,false);
// focus in on the target subkey
KReg.CurSubKey := 'Software\Borland\Delphi\' + vNum + '.0\Palette';
KReg.GetValues(KL);
// stepped through the values list and save the value to the memo
for k := 0 to KL.count-1 do
// skip the section for stay on page
if pos('.StayOnPage',kl.strings[k])=0
then memoRegistryExtract.lines.add(kl.strings[k]);
Application.ProcessMessages;
finally kReg.free;
end;
finally KL.free;
end;
// Now that there is some data in the memo, allow the FillTable button to work
BtnFillTable.enabled := true;
end;procedure TFrmMain.BtnFillTableClick(Sender: TObject);
var
v : integer; // lines index zero based
k,i : integer; // kounters
P,C : string; // page, component
E : integer; // position of the equal sign
SL : TStringList; // StringList to use for breaking things down
slC : integer; // Count of StringList of components for this page
begin
sl := nil;
// You could use a tblPalette.emptyTable here.
// BUT sometimes you forget to inactivate the table while in the IDE [G]
tblPalette.DisableControls;
while tblPalette.RecordCount > 0
do tblPalette.delete;
tblPalette.enableControls;
// disable report button while working ...
BtnReport.enabled := false;
// step through the memo
V := memoRegistryExtract.Lines.Count - 1;
for k := 0 to V
do begin
P := memoRegistryExtract.lines[k];
// look for the equals sign in the value and chop it out,
// while parsing for the page and component
E := pos('=',P);
C := copy(P,E+(2*ChopAt-1),length(P)-E-(2*ChopAt-1));
P := copy(P,ChopAt,E-(2*ChopAt-1));
if pos('.Hidden',P) <> 0 // want to be bothered with the hidden?
then if cbFilterHidden.checked = true
then continue
else p := copy(P,1,pos('.Hidden',P) - 1) + '*';
try SL := TStringList.create;
// Now chop the component names into a list
CommaTextToStringList(sl,c,';');
// loop through the resulting list
slC := sl.Count;
for I := 0 to slC - 1
do begin
tblPalette.Append;
tblPalette.fieldByName('Seq').asInteger := k + 1;
// check the checkbox to see whether to cap names
if cbCapNames.checked = true
then tblPalette.FieldByName('Pg').AsString := uppercase(p)
else tblPalette.FieldByName('Pg').AsString := p;
ttblPalette.FieldByName('Vcl').asString := sl.strings[i];
tblPalette.post;
end;
finally SL.free;
end;
end;
// now it's okay to enable the Report button!
BtnReport.enabled := true;
end;procedure TFrmMain.BtnReportClick(Sender: TObject);
begin
// print whatever report you design
end;procedure TFrmMain.BtnExitClick(Sender: TObject);
begin
close;
end;procedure TFrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
canClose := false;
if not (SourcePalette.state in dsEditModes)
then CanClose := true
else ShowMessage('You are still editing the table, please Post or Cancel');
end;
Gary Mugford
Idea Mechanic
Bramalea ON Canada